package com.sopt.test.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.database.DataSetObserver;
import android.os.Handler;
import android.util.Log;

public class FriendsManager {
	
	public Handler mHandler = new Handler();

	private static FriendsManager sInstance;
	
	public boolean mLoading;
    
	public Context mContext;
    
	public ArrayList<HashMap<String, String>> mLists = new ArrayList<HashMap<String, String>>();
    
    /**
     * Observers interested in changes to the current search results
     */
    private ArrayList<WeakReference<DataSetObserver>> mObservers = 
            new ArrayList<WeakReference<DataSetObserver>>();
    
    public FriendsManager(Context c) {
        mContext = c;
    }
    
	public static FriendsManager getInstance(Context c) {
        if (sInstance == null) {
            sInstance = new FriendsManager(c.getApplicationContext());
        }
        return sInstance;
    }
	
	public boolean isLoading() {
		return mLoading;
	}
	
	public ArrayList<HashMap<String, String>> getLists(){
		return mLists;
	}
	
	public void load(String url) {
        mLoading = true;
        new NetworkThread(url).start();
    }
	
	/**
     * Clear all downloaded content
     */
    public void clear() {
    	mLists.clear();   
        //notifyObservers();
    }
    
    /**
     * Add an item to and notify observers of the change.
     * @param item The item to add
     */
    public void add(HashMap<String, String> item) {
    	mLists.add(item);   
        notifyObservers();
    }
    
    /**
     * @return The number of items displayed so far
     */
    public int size() {
        return mLists.size();
    }

    /**
     * Gets the item at the specified position
     */
    public HashMap<String, String> get(int position) {
        return mLists.get(position);
    }
	
	/**
     * Adds an observer to be notified when the set of items held by this ImageManager changes.
     */
    public void addObserver(DataSetObserver observer) {
        WeakReference<DataSetObserver> obs = new WeakReference<DataSetObserver>(observer);
        mObservers.add(obs);
    }
    
    public ArrayList<WeakReference<DataSetObserver>> getmObservers() {
		return mObservers;
	}
    
	public void notifyObservers() {
		Log.v("changdoc", "HERE????????????????? in notifyObservers");
		
        final ArrayList<WeakReference<DataSetObserver>> observers = mObservers;
        final int count = observers.size();
        
        if(count>0){
        	WeakReference<DataSetObserver> weak = observers.get(count-1);
        	DataSetObserver obs = weak.get();
        	if(obs!=null)obs.onChanged();
        	
        	//observers.remove(count-1);
        }
    }

	/**
     * This thread does the actual work of downloading and parsing data.
     *
     */
    private class NetworkThread extends Thread {
    	private String currentUrl = "";
        public NetworkThread(String url) {
        	currentUrl = url;
        }

        @Override
        public void run() {
            String url = currentUrl;
            Log.v("changdoc", "RUnning..Thread"+url);
            try {
                URI uri = new URI("http", url, null);
                HttpGet get = new HttpGet(uri);
                
                HttpClient client = new DefaultHttpClient();
                HttpResponse response = client.execute(get);
                HttpEntity entity = response.getEntity();
                String str = convertStreamToString(entity.getContent());
                JSONObject json = new JSONObject(str);
                Log.v("changdoc",str);
                parse(json);
            } catch (Exception e) {
            	
            	
            	JSONObject json = new JSONObject();
            	try {
					json.put("result", new JSONObject("{\"exist\":\"Cannot connect ServerT_T\"}"));
				} catch (JSONException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				parse(json);
            } finally {
            	
            }
        }
        
        private void parse(JSONObject json) {
        	try {
        		
              
                  JSONObject obj = json.getJSONObject("result");
                  
                  final HashMap<String, String> item = convertJSONObjectToHashMap(obj); 
                  
                  final boolean done = true;
                  mHandler.post(new Runnable() {
                      public void run() {
                          sInstance.mLoading = !done;
                          sInstance.add(item);
                      }
                  });
           } catch (JSONException e) {
          	Log.e("changdoc", e.getMessage()+"parse");
          }
//            try {
//                JSONArray array = json.getJSONArray("result");
//                int count = array.length();
//                
//                Log.v("changdoc", "json Array Size : "+count);
//                for (int i = 0; i < count; i++) {
//                    JSONObject obj = array.getJSONObject(i);
//                    
//                    final HashMap<String, String> item = convertJSONObjectToHashMap(obj); 
//                    
//                    final boolean done = i == count - 1;
//                    mHandler.post(new Runnable() {
//                        public void run() {
//                            sInstance.mLoading = !done;
//                            sInstance.add(item);
//                        }
//                    });
//                }
//            } catch (JSONException e) {
//            	Log.e("changdoc", e.getMessage());
//            }
        }
        
        private HashMap<String, String> convertJSONObjectToHashMap(JSONObject obj){        	
            Iterator keys = obj.keys();
            
            HashMap<String, String> hm = new HashMap<String, String>();
            
            while(keys.hasNext()){
            	String curKey = keys.next().toString();
            	try {
					hm.put(curKey, obj.getString(curKey));
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
        	return hm;
        }

        private String convertStreamToString(InputStream is) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is), 8*1024);
            StringBuilder sb = new StringBuilder();
     
            String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
     
            return sb.toString();
        }

    }
}
